#include "main.h"

void BSP_CLK_Init(void)
{
    stc_clock_xtal_init_t stcXtalInit;
    stc_clock_pll_init_t stcPLLHInit;

    /* PCLK0, HCLK Max 200MHz */
    /* PCLK1, PCLK4, EX BUS Max 100MHz */
    /* PCLK2 Max 75MHz */
    /* PCLK3 Max 50MHz */
    CLK_SetClockDiv(CLK_BUS_CLK_ALL,
                    (CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | CLK_PCLK2_DIV4 |
                     CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2 | CLK_EXCLK_DIV2 |
                     CLK_HCLK_DIV1));

    GPIO_AnalogCmd(GPIO_PORT_H, GPIO_PIN_00 | GPIO_PIN_01, ENABLE);
    (void)CLK_XtalStructInit(&stcXtalInit);
    /* Config Xtal and enable Xtal */
    stcXtalInit.u8Mode   = CLK_XTAL_MD_OSC;
    stcXtalInit.u8Drv    = CLK_XTAL_DRV_ULOW;
    stcXtalInit.u8State  = CLK_XTAL_ON;
    stcXtalInit.u8StableTime = CLK_XTAL_STB_2MS;
    (void)CLK_XtalInit(&stcXtalInit);

    (void)CLK_PLLStructInit(&stcPLLHInit);
    /* VCO = (8/1)*100 = 800MHz*/
    stcPLLHInit.u8PLLState = CLK_PLL_ON;
    stcPLLHInit.PLLCFGR = 0UL;
    stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLN = 100UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLQ = 16UL - 1UL;//50MHZ
    stcPLLHInit.PLLCFGR_f.PLLR = 16UL - 1UL;
    stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL;
    (void)CLK_PLLInit(&stcPLLHInit);

    /* Highspeed SRAM, SRAM0 set to 0 Read/Write wait cycle */
    SRAM_SetWaitCycle((SRAM_SRAMH | SRAM_SRAM0), SRAM_WAIT_CYCLE0, SRAM_WAIT_CYCLE0);
    /* SRAMB set to 1 Read/Write wait cycle */
    SRAM_SetWaitCycle(SRAM_SRAMB, SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1);
    /* 3 cycles for 150 ~ 200MHz */
    (void)EFM_SetWaitCycle(EFM_WAIT_CYCLE3);
    (void)EFM_ICacheCmd(ENABLE);
    (void)EFM_DCacheCmd(ENABLE);
    (void)EFM_PrefetchCmd(ENABLE);
    /* 3 cycles for 150 ~ 200MHz */
    GPIO_SetReadWaitCycle(GPIO_RD_WAIT3);
    CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL);
}
///**
// * @brief  BSP printf device, clock and port pre-initialize.
// * @param  [in] vpDevice                Pointer to print device
// * @param  [in] u32Baudrate             Print device communication baudrate
// * @retval int32_t:
// *           - LL_OK:                   Initialize successfully.
// *           - LL_ERR:                  Initialize unsuccessfully.
// *           - LL_ERR_INVD_PARAM:       The u32Baudrate value is 0.
// */
//int32_t BSP_PRINTF_Preinit(void *vpDevice, uint32_t u32Baudrate)
//{
//    uint32_t u32Div;
//    float32_t f32Error;
//    stc_usart_uart_init_t stcUartInit;
//    int32_t i32Ret = LL_ERR_INVD_PARAM;

//    (void)vpDevice;

//    if (0UL != u32Baudrate) {
//        /* Set TX port function */
//        GPIO_SetFunc(BSP_PRINTF_PORT, BSP_PRINTF_PIN, BSP_PRINTF_PORT_FUNC);

//        /* Enable clock  */
//        FCG_Fcg3PeriphClockCmd(BSP_PRINTF_DEVICE_FCG, ENABLE);

//        /* Configure UART */
//        (void)USART_UART_StructInit(&stcUartInit);
//        stcUartInit.u32OverSampleBit = USART_OVER_SAMPLE_8BIT;
//        (void)USART_UART_Init(BSP_PRINTF_DEVICE, &stcUartInit, NULL);

//        for (u32Div = 0UL; u32Div <= USART_CLK_DIV64; u32Div++) {
//            USART_SetClockDiv(BSP_PRINTF_DEVICE, u32Div);
//            i32Ret = USART_SetBaudrate(BSP_PRINTF_DEVICE, u32Baudrate, &f32Error);
//            if ((LL_OK == i32Ret) && \
//                    ((-BSP_PRINTF_BAUDRATE_ERR_MAX <= f32Error) && (f32Error <= BSP_PRINTF_BAUDRATE_ERR_MAX))) {
//                USART_FuncCmd(BSP_PRINTF_DEVICE, USART_TX, ENABLE);
//                break;
//            } else {
//                i32Ret = LL_ERR;
//            }
//        }
//    }

//    return i32Ret;
//}
void ShowSystemClk(void)
{
    stc_clock_freq_t clkinfo;
    stc_pll_clock_freq_t pllinfo;
    CLK_GetPLLClockFreq(&pllinfo);
    CLK_GetClockFreq(&clkinfo);
    DDL_Printf("hclk = %d\r\n", clkinfo.u32HclkFreq);
    DDL_Printf("exclk = %d\r\n", clkinfo.u32ExclkFreq);
    DDL_Printf("pclk0 = %d\r\n", clkinfo.u32Pclk0Freq);
    DDL_Printf("pclk1 = %d\r\n", clkinfo.u32Pclk1Freq);
    DDL_Printf("pclk2 = %d\r\n", clkinfo.u32Pclk2Freq);
    DDL_Printf("pclk3 = %d\r\n", clkinfo.u32Pclk3Freq);
    DDL_Printf("pclk4 = %d\r\n", clkinfo.u32Pclk4Freq);
    DDL_Printf("sysclk = %d\r\n", clkinfo.u32SysclkFreq);
    DDL_Printf("PLLHP = %d\r\n", pllinfo.u32PllP);
    DDL_Printf("PLLHQ = %d\r\n", pllinfo.u32PllQ);
    DDL_Printf("PLLHR = %d\r\n", pllinfo.u32PllR);
}
#define APPADDR 0x8000
void system_hardware_init(void)
{
#if (LL_ICG_ENABLE != DDL_ON)    
    SCB->VTOR = ((uint32_t) APPADDR & SCB_VTOR_TBLOFF_Msk);
#endif    
    BSP_CLK_Init();
    BSP_IO_Init();
    bsp_adc_init();
    bsp_uart1_init();
    bsp_timera1_init();
    DDL_PrintfInit(BSP_PRINTF_DEVICE, 2000000UL, BSP_PRINTF_Preinit);
    DDL_Printf("system initialized!\r\n");
    ShowSystemClk();
    DDL_Printf("system Version = 0x%X\r\n",GetVersion());
}
/**
 * @brief  SysTick interrupt callback function.
 * @param  None
 * @retval None
 */
void SysTick_Handler(void)
{
    osSystickHandler();
    SysTick_IncTick();
}
int main(void)
{
    LL_PERIPH_WE(LL_PERIPH_ALL);
    system_hardware_init();
    LL_PERIPH_WP(LL_PERIPH_ALL);
    OS_Start();
    while(1)
    {
        ;
    }
}
